/**
 * File InformationAgentMessageFactory.java created by Pablo Díaz Fernández
 * on 21/04/2012 for the project supply-chain-simulator
 */
package org.lsk.pfc.scsim.model.messages;

import org.lsk.pfc.scsim.model.persistence.dto.RequestDTO;

import jade.core.AID;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

/**
 * Helper that deals with all the messages that sends or receives each
 * {@link InformationAgent}.
 * 
 * @author Pablo Díaz Fernández
 */
public final class InformationAgentMessageFactory {
	/**
	 * Original requester of the message.
	 */
	private static final String REQUESTER = "__requester";

	/**
	 * Content of a needs related message.
	 */
	public static final String NEEDS_MESSAGE = "__needs";
	/**
	 * Content of a stocks related message.
	 */
	public static final String STOCKS_MESSAGE = "__stocks";
	/**
	 * Content of a requests message.
	 */
	public static final String REQUESTS_MESSAGE = "__requests";

	/**
	 * Protected constructor. Only {@link MessageFactory} can instantiate it.
	 */
	protected InformationAgentMessageFactory() {
	}

	/**
	 * Message template to match the response from an Information agent.
	 */
	public static final MessageTemplate RESPONSE_MSG_TEMPLATE = MessageTemplate
	        .and(MessageTemplate.MatchOntology(MessageFactory.COMMAND_ONTOLOGY),
	                MessageTemplate.MatchPerformative(ACLMessage.INFORM));

	/**
	 * Creates a message to ask information agent to get needs for current tick.
	 * 
	 * @param agentTarget
	 *            AID of the agent asked for info.
	 * @param agentSource
	 *            AID of the agent that asks for info.
	 * @param tickNo
	 *            Number of the current time tick.
	 * @param message
	 *            Message to send to the info agent.
	 * @return {@link ACLMessage} Built.
	 */
	public ACLMessage queryMessage(final AID agentTarget,
	        final AID agentSource, final Long tickNo, final String message) {
		return MessageFactory.getTickBasedMessage(agentTarget, agentSource,
		        MessageFactory.COMMAND_ONTOLOGY, ACLMessage.REQUEST, tickNo,
		        message);
	}

	/**
	 * Creates a response message from the information agent.
	 * 
	 * @param message
	 *            Message to send to the info agent.
	 * @param inResponseTo
	 *            {@link ACLMessage} origin.
	 * @return {@link ACLMessage} Built.
	 */
	public ACLMessage responseMessage(final String message,
	        final ACLMessage inResponseTo) {
		ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
		msg.addReceiver(inResponseTo.getSender());
		msg.setOntology(MessageFactory.COMMAND_ONTOLOGY);
		msg.setContent(message);
		return msg;
	}

	/**
	 * Obtains a {@link RequestDTO} with the data from the provided message.
	 * 
	 * @param message
	 *            {@link ACLMessage} to parse.
	 * @return {@link RequestDTO} obtained.
	 */
	public RequestDTO parseRequestPersistMessage(final ACLMessage message) {
		RequestDTO requestDTO = new RequestDTO();

		requestDTO.setSourceName(MessageFactory.extractMASName(message
		        .getUserDefinedParameter(REQUESTER)));
		requestDTO.setTargetName(MessageFactory.extractMASName(message
		        .getSender()));
//TODO add the rest of the details of the message
		return requestDTO;
	}

	/**
	 * Tests if the message matches a request for needs message.
	 * 
	 * @param msg
	 *            {@link ACLMessage} Message to test.
	 * @return <code>true</code> if the message is a new tick notification.
	 */
	public boolean isGetNeeds(final ACLMessage msg) {
		return MessageFactory.matches(msg, MessageFactory.COMMAND_ONTOLOGY,
		        ACLMessage.REQUEST, NEEDS_MESSAGE);
	}

	/**
	 * Tests if the message matches a request for needs stocks.
	 * 
	 * @param msg
	 *            {@link ACLMessage} Message to test.
	 * @return <code>true</code> if the message is a new tick notification.
	 */
	public boolean isGetStocks(final ACLMessage msg) {
		return MessageFactory.matches(msg, MessageFactory.COMMAND_ONTOLOGY,
		        ACLMessage.REQUEST, STOCKS_MESSAGE);
	}

	/**
	 * Tests if the message matches a request for needs message.
	 * 
	 * @param msg
	 *            {@link ACLMessage} Message to test.
	 * @return <code>true</code> if the message is a new tick notification.
	 */
	public boolean isPersistRequests(final ACLMessage msg) {
		return MessageFactory.matches(msg, MessageFactory.COMMAND_ONTOLOGY,
		        ACLMessage.INFORM, REQUESTS_MESSAGE);
	}
}
